package com.hitqz.robot.biz.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import com.google.common.cache.Cache;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hitqz.robot.api.business.dto.*;
import com.hitqz.robot.api.business.entity.RobotEntity;
import com.hitqz.robot.api.business.entity.RobotJobEntity;
import com.hitqz.robot.api.business.entity.RobotWarningRecordEntity;
import com.hitqz.robot.api.business.entity.TicketsEntity;
import com.hitqz.robot.api.business.params.HomeTicketsParams;
import com.hitqz.robot.api.business.params.SortByTypeParams;
import com.hitqz.robot.api.business.vo.*;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author xupkun
 * @date 2024/12/2
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/home")
@Tag(name = "大屏-首页数据")
@Slf4j
public class HomeController {

    private final RobotService robotService;

    private final TicketsService ticketsService;

    private final RobotWarningRecordService robotWarningRecordService;

    private final PatrolResultService patrolResultService;

    private final RobotJobService robotJobService;

//    private final InfluxDBService influxService;


    @Operation(summary = "首页-机器人状态(包含任务信息)", description = "机器人状态")
    @GetMapping("/getRobotStatusList")
    public R<List<HomeRobotVo>> getRobotStatusList() {
        List<HomeRobotVo> homeRobotVoList = Lists.newArrayList();
        Cache<String, RobotClientSummaryDto> robotStatusCache = SpringUtil.getBean("robotCache");

        robotService.list().forEach(robotEntity -> {
            HomeRobotVo vo = new HomeRobotVo();
            vo.setId(robotEntity.getId().toString());
            vo.setSn(robotEntity.getRobotSn());
            vo.setName(robotEntity.getRobotName());
            RobotClientSummaryDto summaryDto = robotStatusCache.getIfPresent(robotEntity.getRobotSn());
            vo.setOnlineStatusStr(summaryDto == null ? "离线" : summaryDto.getStatus().getOnlineStatusStr());
            vo.setSpeed(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getSpeed).orElse(""));
            vo.setBattery(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getBattery).orElse(""));
            vo.setVoltage(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getVoltage).orElse(""));
            vo.setCurrent(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getCurrent).orElse(""));
            vo.setErrorStatusStr(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getErrorStatusStr).orElse("无"));
            vo.setEmergencyStopStr(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getEmergencyStopStr).orElse("无"));
            vo.setNormalFlag(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getErrorStatus).orElse(0)==0);
            Integer onlineStatus = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getOnlineStatus).orElse(0);
            Integer chargeStatus = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getChargeStatus).orElse(0);
            String workStatusStr = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getWorkStatusStr).orElse("无");
            String batteryPercent = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getStatus).map(RobotStatusDto::getBattery).orElse("");
            List<RobotCustomInfoDto> robotCustomInfoDtos = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getOtherInfo).map(RobotOtherInfoDto::getCustomInfos).orElse(new ArrayList<>());
            for (RobotCustomInfoDto robotCustomInfoDto : robotCustomInfoDtos) {
                if (Objects.equals(robotCustomInfoDto.getKey(),"totalMileage")) {
                    vo.setTotalMileage(robotCustomInfoDto.getValue());
                    break;
                }
            }
            vo.setBatteryPercent(StrUtil.isNotBlank(batteryPercent) ? batteryPercent + "%" : "");
            vo.setTaskPercent("0%");
            if (onlineStatus == 0){
                vo.setRunStatus("离线");
            }else if (chargeStatus == 1){
                vo.setRunStatus("充电中");
            }else if (workStatusStr.contains("空闲")){
                vo.setRunStatus("待机中");
            }else if (workStatusStr.contains("作业")){
                vo.setRunStatus("巡检中");
            }else {
                vo.setRunStatus(workStatusStr);
            }
            if (Objects.equals(vo.getRunStatus(), "巡检中")){
                vo.setTaskPercent(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getPatrolTask).map(RobotPatrolTaskDto::getPercent).orElse(0)+"%");
            }
            vo.setWorkStatusStr(vo.getRunStatus());
            vo.setPatrolName(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getName).orElse(""));
            vo.setPatrolStatus("patrolling");
            vo.setDeviceName(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getPatrolTask).map(RobotPatrolTaskDto::getDevName).orElse(""));
            vo.setPatrolResult(Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getPatrolTask).map(RobotPatrolTaskDto::getResultStr).orElse(""));
            String checkTime = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getPatrolTask).map(RobotPatrolTaskDto::getCheckTime).orElse("");
            vo.setCheckTime(StrUtil.isNotBlank(checkTime) ? DateUtil.parse(checkTime,"yyyy-MM-dd HH:mm:ss"):null);
            vo.setLastInvokeResult("success");
            String lastStartTime = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getLastTaskStartTime).orElse("");
            String lastEndTime = Optional.ofNullable(summaryDto).map(RobotClientSummaryDto::getTask).map(RobotTaskDto::getLastTaskEndTime).orElse("");
            vo.setLastStartTime(StrUtil.isNotBlank(lastStartTime)? DateUtil.parse(lastStartTime,"yyyy-MM-dd HH:mm:ss") : null); // 1小时前
            vo.setLastEndTime(StrUtil.isNotBlank(lastEndTime)? DateUtil.parse(lastEndTime,"yyyy-MM-dd HH:mm:ss") : null); // 30分钟前
            vo.setNextInvokeTime(null);
            if (StrUtil.isBlank(vo.getPatrolName())) {
                List<RobotJobEntity> jobs = robotJobService.list(Wrappers.<RobotJobEntity>lambdaQuery().eq(RobotJobEntity::getGroupId, robotEntity.getGroupId()).eq(RobotJobEntity::getEnable, 1));
                vo.setPatrolName("无启用的定时任务");
                for (RobotJobEntity job : jobs) {
                    if (job != null && StrUtil.isNotBlank(job.getCron())) {
                        // Quartz cron 表达式
                        String cronExpr = job.getCron();
                        // 使用 Quartz 格式的解析器
                        CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
                        Cron cron = parser.parse(cronExpr);
                        // 当前时间
                        ZonedDateTime now = ZonedDateTime.now();
                        // 计算下一次执行时间
                        ExecutionTime executionTime = ExecutionTime.forCron(cron);
                        Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(now);
                        nextExecution.ifPresentOrElse(
                                time -> {
                                    if (vo.getNextInvokeTime()==null) {
                                        vo.setNextInvokeTime(DateUtil.date(time.toLocalDateTime()));
                                        vo.setPatrolName(job.getName());
                                    }else if (vo.getNextInvokeTime().after(DateUtil.date(time.toLocalDateTime()))){
                                        vo.setNextInvokeTime(DateUtil.date(time.toLocalDateTime()));
                                        vo.setPatrolName(job.getName());
                                    }
                                },
                                () -> {}
                        );
                    }
                }
            }
            homeRobotVoList.add(vo);
        });

        return R.ok(homeRobotVoList);
    }

    @Operation(summary = "七日告警数", description = "七日告警数")
    @GetMapping("/get7DaysWarningNumber")
    public R<List<RobotWarningStatisticsVo>> get7DaysWarningNumber(String clientId) {
        try {
            List<RobotWarningStatisticsVo> robotWarningRecordVos = new ArrayList<>();
            List<RobotWarningRecordEntity> list =
                    robotWarningRecordService.list(Wrappers.<RobotWarningRecordEntity>lambdaQuery().like(!StringUtils.isBlank(clientId),RobotWarningRecordEntity::getServiceId,clientId)
                            .between(RobotWarningRecordEntity::getTime, DateUtil.offsetDay(new Date(), -7), new Date()));


            List<RobotWarningRecordEntity> typeList =
                    robotWarningRecordService.list(Wrappers.<RobotWarningRecordEntity>lambdaQuery()
                            .between(RobotWarningRecordEntity::getTime, DateUtil.offsetDay(new Date(), -7), new Date()));

            Set<String> types =
                    typeList.stream().map(x -> x.getTitle().split(":")[1].replace("告警", "")).distinct().collect(Collectors.toSet());


            Map<String, List<RobotWarningRecordEntity>> map = list.stream().collect(Collectors.groupingBy(
                    f -> DateUtil.format(f.getTime(), "yyyy-MM-dd")
            ));
            List<String> dateStrList = map.keySet().stream().sorted(Comparator.comparing(DateUtil::parse)).toList();
            for (String dateStr : dateStrList) {
                RobotWarningStatisticsVo robotWarningStatisticsVo = new RobotWarningStatisticsVo();
                robotWarningStatisticsVo.setDate(DateUtil.parse(dateStr, "yyyy-MM-dd"));
                List<RobotWarningRecordEntity> dayList = map.get(dateStr);
                Map<String, List<RobotWarningRecordEntity>> collect = dayList.stream().filter(f->f.getTitle().contains(":"))
                        .collect(Collectors.groupingBy(f -> f.getTitle().split(":")[1]));
                List<RobotWarningStatisticsVo.WarningNumVo> warningDayNumList = new ArrayList<>();
                for (String type : collect.keySet()) {
                    RobotWarningStatisticsVo.WarningNumVo warningNumVo = new RobotWarningStatisticsVo.WarningNumVo();
                    warningNumVo.setType(type.replace("告警", ""));
                    warningNumVo.setNumber(collect.get(type).size());
                    warningNumVo.setPercent(collect.get(type).size() * 100 / dayList.size() + "");
                    warningDayNumList.add(warningNumVo);
                }
                List<String> keys = warningDayNumList.stream().map(x -> x.getType()).toList();
                for (String type : types) {
                    if(!keys.contains(type)){
                        RobotWarningStatisticsVo.WarningNumVo warningNumVo = new RobotWarningStatisticsVo.WarningNumVo();
                        warningNumVo.setType(type);
                        warningNumVo.setNumber(0);
                        warningNumVo.setPercent(0 + "");
                        warningDayNumList.add(warningNumVo);
                    }
                }
                robotWarningStatisticsVo.setWarningDayNumList(warningDayNumList);
                robotWarningRecordVos.add(robotWarningStatisticsVo);
            }
            return R.ok(robotWarningRecordVos);
        }catch (Exception e) {
            return R.failed();
        }
    }



    @Operation(summary = "告警数列表", description = "告警数列表")
    @GetMapping("/getRobotWarningList")
    public R<List<HomeRobotWarningVo>> getRobotWarningList() {
        List<RobotWarningRecordEntity> list = robotWarningRecordService.list(Wrappers.<RobotWarningRecordEntity>lambdaQuery().orderByDesc(RobotWarningRecordEntity::getTime).last("limit 10"));
        List<HomeRobotWarningVo> vos = new ArrayList<>();
        list.forEach(warning->{
            HomeRobotWarningVo homeRobotWarningVo = new HomeRobotWarningVo();
            homeRobotWarningVo.setId(warning.getId());
            String[] split = warning.getTitle().split(":");
            homeRobotWarningVo.setName(split[0]);
            homeRobotWarningVo.setPatrolType(split[split.length-1].replace("告警",""));
            homeRobotWarningVo.setContent(warning.getContent());
            homeRobotWarningVo.setTime(warning.getTime());
            homeRobotWarningVo.setLevel(warning.getLevel());
            String levelStr = switch(warning.getLevel()){
                case 0->"告警";
                case 1->"预警";
                default -> "提醒";
            };
            homeRobotWarningVo.setLevelStr(levelStr);
            homeRobotWarningVo.setFlag(warning.getFlag());
            vos.add(homeRobotWarningVo);
        });
        return R.ok(vos);
    }



    @Operation(summary = "本月告警统计", description = "本月告警统计")
    @GetMapping("/getRobotWarningByMonth")
    public R<List<RobotWarningStatisticsVo.WarningNumVo>> getRobotWarningByMonth() {
        List<RobotWarningStatisticsVo.WarningNumVo> monthList =  new ArrayList<>();
        List<RobotWarningRecordEntity> list = robotWarningRecordService.list(Wrappers.<RobotWarningRecordEntity>lambdaQuery().between(RobotWarningRecordEntity::getTime,DateUtil.beginOfMonth(new Date()),DateUtil.endOfMonth(new Date())));
        Map<String, List<RobotWarningRecordEntity>> map = list.stream().filter(f->f.getTitle().contains(":")).collect(Collectors.groupingBy(
                f -> f.getTitle().split(":")[1]
        ));
        for (String type : map.keySet()) {
            RobotWarningStatisticsVo.WarningNumVo warningNumVo = new RobotWarningStatisticsVo.WarningNumVo();
            warningNumVo.setType(type.replace("告警","" ));
            warningNumVo.setNumber(map.get(type).size());
            warningNumVo.setPercent(map.get(type).size() * 100 / list.size() + "");
            monthList.add(warningNumVo);
        }
        return R.ok(monthList);
    }



    @Operation(summary = "氢气7天溶度检测", description = "氢气7天溶度检测")
    @GetMapping("/getH27DayData")
    public R<List<RobotWarningStatisticsVo>> getH27DayData() {
        List<RobotWarningStatisticsVo> robotWarningRecordVos = generateH27DayData();
        return R.ok(robotWarningRecordVos);
    }

    private List<RobotWarningStatisticsVo> generateH27DayData() {
        List<RobotWarningStatisticsVo> result = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -6); // Start from 6 days ago
        String[] warningTypes = robotService.list().stream().map(RobotEntity::getRobotName).toArray(String[]::new);
        Random random = new Random();

        for (int i = 0; i < 7; i++) {
            RobotWarningStatisticsVo dailyData = new RobotWarningStatisticsVo();
            dailyData.setDate(calendar.getTime());

            List<RobotWarningStatisticsVo.WarningNumVo> dailyStats = new ArrayList<>();
            int total = 0;

            // First generate random numbers for each type
            for (String type : warningTypes) {
                RobotWarningStatisticsVo.WarningNumVo stat = new RobotWarningStatisticsVo.WarningNumVo();
                stat.setType(type);
                int num = 0; // Random number between 10-60
                stat.setNumber(num);
                dailyStats.add(stat);
                total += num;
            }

            // Then calculate percentages
            for (RobotWarningStatisticsVo.WarningNumVo stat : dailyStats) {
                double percent = (stat.getNumber() * 100.0) / total;
                stat.setPercent(String.format("%.1f%%", percent));
            }

            dailyData.setWarningDayNumList(dailyStats);
            result.add(dailyData);

            calendar.add(Calendar.DAY_OF_YEAR, 1); // Move to next day
        }

        return result;
    }






    @Operation(summary = "首页-异常数据统计", description = "异常数据统计")
    @GetMapping("/errorData")
    public R<List<HomeErrorStaticDto>> errorData() {
        List<HomeErrorStaticDto> list = Lists.newArrayList();

        HomeErrorStaticDto errorStaticDto = new HomeErrorStaticDto();
        //errorStaticDto.setLabel("驱动器异常");
        //errorStaticDto.setNumber(10);
        //errorStaticDto.setPercent("6.89");
        //list.add(errorStaticDto);
        //
        //errorStaticDto = new HomeErrorStaticDto();
        //errorStaticDto.setNumber(30);
        //errorStaticDto.setLabel("导航异常");
        //errorStaticDto.setPercent("20");
        //list.add(errorStaticDto);
        //
        //
        //errorStaticDto = new HomeErrorStaticDto();
        //errorStaticDto.setNumber(13);
        //errorStaticDto.setLabel("取油异常");
        //errorStaticDto.setPercent("8.96");
        //list.add(errorStaticDto);

        errorStaticDto = new HomeErrorStaticDto();
        errorStaticDto.setNumber(21);
        errorStaticDto.setLabel("鸟粪");
        errorStaticDto.setPercent("14.48");
        list.add(errorStaticDto);

        errorStaticDto = new HomeErrorStaticDto();
        errorStaticDto.setNumber(15);
        errorStaticDto.setLabel("裂纹");
        errorStaticDto.setPercent("10.34");
        list.add(errorStaticDto);

        errorStaticDto = new HomeErrorStaticDto();
        errorStaticDto.setNumber(17);
        errorStaticDto.setLabel("紧固件丢失");
        errorStaticDto.setPercent("11.72");
        list.add(errorStaticDto);

        errorStaticDto = new HomeErrorStaticDto();
        errorStaticDto.setNumber(19);
        errorStaticDto.setLabel("其他异物");
        errorStaticDto.setPercent("13.1");
        list.add(errorStaticDto);

        return R.ok(list);
    }

    @Operation(summary = "首页-在线离线设备计算", description = "在线离线设备计算")
    @GetMapping("/robotOnlineStatic")
    public R<RobotOnlineOrOffLineVo> onlineOrOffline() {
        RobotOnlineOrOffLineVo vo = new RobotOnlineOrOffLineVo();
        int offLineNumber = 0, onlineNumber = 0;
        List<RobotEntity> robotEntityList = robotService.list();
        Cache<String, RobotClientSummaryDto> posInfoDtoCache = SpringUtil.getBean("robotCache");
        vo.setTotalNumber(robotEntityList.size());
        for (RobotEntity robotEntity : robotEntityList) {
            RobotClientSummaryDto robotClientSummaryDto = posInfoDtoCache.getIfPresent(robotEntity.getRobotSn());
            if (robotClientSummaryDto != null && robotClientSummaryDto.getStatus().getOnlineStatus() == 1) {
                onlineNumber++;
            } else {
                offLineNumber++;
            }
        }
        vo.setOnlineNumber(onlineNumber);
        vo.setOfflineNumber(offLineNumber);
        return R.ok(vo);
    }

    @Operation(summary = "首页-统计设备等总数量", description = "在线离线设备计算")
    @GetMapping(value = "countTotal")
    public R<HomeTotalCountVo> countTotal() {
        HomeTotalCountVo homeTotalCountVo = new HomeTotalCountVo();
        homeTotalCountVo.setRobotNumber((int) robotService.count());
        homeTotalCountVo.setTotalTaskNumber((int) ticketsService.count());
        homeTotalCountVo.setCheckNumber((int) patrolResultService.count());
        homeTotalCountVo.setWarningNumber((int) robotWarningRecordService.count());
        return R.ok(homeTotalCountVo);
    }


    @Operation(summary = "首页-任务记录", description = "任务记录")
    @PostMapping("tickets")
    public R<List<HomeTicketsVo>> tickets(@RequestBody HomeTicketsParams params
    ) {

        List<HomeTicketsVo> homeTicketsVos = Lists.newArrayList();
        LambdaQueryWrapper<TicketsEntity> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(params.getStartDate())) {
            wrapper.gt(TicketsEntity::getCreateTime, params.getStartDate() + " 00:00:00");
        }
        if (StrUtil.isNotBlank(params.getEndDate())) {
            wrapper.le(TicketsEntity::getCreateTime, params.getEndDate() + " 00:00:00");
        }
        List<TicketsEntity> ticketsEntities = ticketsService.list(wrapper
                .orderByDesc(TicketsEntity::getId)
        );
        for (TicketsEntity ticketsEntity : ticketsEntities) {
            HomeTicketsVo homeTicketsVo = new HomeTicketsVo();
            homeTicketsVo.setStatus(ticketsEntity.getStatus());
            homeTicketsVo.setStatusStr("执行中");
            homeTicketsVo.setTaskName(ticketsEntity.getName());
            homeTicketsVo.setRobotName(ticketsEntity.getAllotRobotName());
            homeTicketsVo.setStartTime(ticketsEntity.getCreateTime());
            homeTicketsVo.setEndTime(ticketsEntity.getFinishTime());
            homeTicketsVos.add(homeTicketsVo);
        }
        return R.ok(homeTicketsVos);
    }


    @Operation(summary = "首页-任务与报警数量统计", description = "任务与报警数量统计")
    @PostMapping("ticketsAndWarningStatic")
    public R<List<DateAndStaticNumVo>> ticketsAndWarningStatic(@RequestBody SortByTypeParams params
    ) {
        List<DateAndStaticNumVo> tickets = Lists.newArrayList();
        Map<String, Long> warningBy = Maps.newHashMap();
        Map<String, Long> countTasksBy = Maps.newHashMap();
        if (Objects.equals(params.getSort(), "1")) {
            // 年
            List<TicketsEntity> ticketsEntities = ticketsService.list();
            List<RobotWarningRecordEntity> warningRecordEntities = robotWarningRecordService.list();
            countTasksBy = countTasksByYear(ticketsEntities);
            warningBy = countWarningByYear(warningRecordEntities);
        } else if (Objects.equals(params.getSort(), "0")) {
            // 月
            List<TicketsEntity> ticketsEntities = ticketsService.list(Wrappers.<TicketsEntity>lambdaQuery()
                    .gt(TicketsEntity::getCreateTime, DateUtil.beginOfYear(DateUtil.date()).toJdkDate())
                    .lt(TicketsEntity::getCreateTime, DateUtil.endOfYear(DateUtil.date()).toJdkDate())
                    .orderByDesc(TicketsEntity::getCreateTime)
            );
            List<RobotWarningRecordEntity> warningRecordEntities =
                    robotWarningRecordService.list(Wrappers.<RobotWarningRecordEntity>lambdaQuery()
                            .gt(RobotWarningRecordEntity::getTime, DateUtil.beginOfYear(DateUtil.date()).toJdkDate())
                            .lt(RobotWarningRecordEntity::getTime, DateUtil.endOfYear(DateUtil.date()).toJdkDate())
                            .orderByDesc(RobotWarningRecordEntity::getTime)
                    );
            countTasksBy = countTasksByMonth(ticketsEntities);
            warningBy = countWarningByMonth(warningRecordEntities);
        }
        for (String s : countTasksBy.keySet()) {
            DateAndStaticNumVo dateAndStaticNumVo = new DateAndStaticNumVo();
            dateAndStaticNumVo.setDate(s);
            dateAndStaticNumVo.setTicketsNum(countTasksBy.get(s).intValue());
            dateAndStaticNumVo.setWarningNum(0);
            tickets.add(dateAndStaticNumVo);
        }
        for (String s : warningBy.keySet()) {
            Optional<DateAndStaticNumVo> optional = tickets.stream().filter(t -> t.getDate().equals(s)).findFirst();
            DateAndStaticNumVo vo = new DateAndStaticNumVo();
            vo.setDate(s);
            if (optional.isPresent()) {
                vo = optional.get();
                tickets.remove(vo);
            } else {
                vo.setTicketsNum(0);
            }
            vo.setWarningNum(warningBy.get(s).intValue());
            tickets.add(vo);
        }
        return R.ok(tickets);
    }


    private Map<String, Long> countTasksByMonth(List<TicketsEntity> taskList) {
        List<TransStaticDateDto> convertedTaskList = taskList.stream()
                .map(task -> new TransStaticDateDto(task.getName(),
                        DateUtil.date(task.getCreateTime()).toLocalDateTime().toLocalDate()))
                .collect(Collectors.toList());

        Map<String, List<TransStaticDateDto>> tasksByMonth =
                convertedTaskList.stream().collect(Collectors.groupingBy(
                        task -> task.getDate().getYear() + "-" + String.format("%02d",
                                task.getDate().getMonthValue())));
        // 统计每个月分组后的任务数量
        return tasksByMonth.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> (long) entry.getValue().size()));
    }


    private Map<String, Long> countTasksByYear(List<TicketsEntity> taskList) {
        List<TransStaticYearDto> convertedTaskList = taskList.stream()
                .map(task -> new TransStaticYearDto(task.getName(),
                        DateUtil.date(task.getCreateTime()).toLocalDateTime().toLocalDate().getYear()))
                .collect(Collectors.toList());

        Map<String, List<TransStaticYearDto>> tasksByMonth =
                convertedTaskList.stream().collect(Collectors.groupingBy(
                        task -> "" + task.getYear()));
        // 统计每个月分组后的任务数量
        return tasksByMonth.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> (long) entry.getValue().size()));
    }

    private Map<String, Long> countWarningByMonth(List<RobotWarningRecordEntity> taskList) {
        List<TransStaticDateDto> convertedTaskList = taskList.stream()
                .map(task -> new TransStaticDateDto(task.getTitle(),
                        DateUtil.date(task.getTime()).toLocalDateTime().toLocalDate()))
                .collect(Collectors.toList());

        Map<String, List<TransStaticDateDto>> tasksByMonth =
                convertedTaskList.stream().collect(Collectors.groupingBy(
                        task -> task.getDate().getYear() + "-" + String.format("%02d",
                                task.getDate().getMonthValue())));
        // 统计每个月分组后的任务数量
        return tasksByMonth.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> (long) entry.getValue().size()));
    }


    private Map<String, Long> countWarningByYear(List<RobotWarningRecordEntity> taskList) {
        List<TransStaticYearDto> convertedTaskList = taskList.stream()
                .map(task -> new TransStaticYearDto(task.getTitle(),
                        DateUtil.date(task.getTime()).toLocalDateTime().toLocalDate().getYear()))
                .collect(Collectors.toList());

        Map<String, List<TransStaticYearDto>> tasksByMonth =
                convertedTaskList.stream().collect(Collectors.groupingBy(
                        task -> "" + task.getYear()));
        // 统计每个月分组后的任务数量
        return tasksByMonth.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> (long) entry.getValue().size()));
    }


}
